﻿using System;
using System.Reflection;

namespace GenerateAccessors
{
	class MemberInfoAdapter
	{
		public readonly MemberInfo MemberInfo;
		public readonly string Name;
		public readonly Type ReflectedType;
		public readonly bool IsReflectedTypePublic;
		public readonly bool IsPublic;
		// for properties that have public get but non-public set
		public readonly bool IsPublicGet;
		public readonly bool IsStatic;
		public readonly Type ReturnType;
		public readonly string GetterMethod;

		private MemberInfoAdapter(MemberInfo info)
		{
			MemberInfo = info;
			Name = info.Name;
			ReflectedType = info.ReflectedType;
			IsReflectedTypePublic = info.ReflectedType.IsEntirelyPublic();
		}

		public MemberInfoAdapter(FieldInfo info)
			: this((MemberInfo)info)
		{
			IsPublic = info.IsPublic;
			IsPublicGet = info.IsPublic;
			IsStatic = info.IsStatic;
			ReturnType = info.FieldType;
			GetterMethod = "GetField";
		}

		public MemberInfoAdapter(PropertyInfo info, bool write)
			: this((MemberInfo)info)
		{
			var attrib = write ? info.GetSetMethod(true).Attributes : info.GetGetMethod(true).Attributes;
			IsPublic = (attrib & MethodAttributes.Public) == MethodAttributes.Public;
			IsStatic = (attrib & MethodAttributes.Static) == MethodAttributes.Static;
			// Even though it seems impossible to declare in C#, mscorlib seems to contain write-only properties.
			var attribGet = info.CanRead ? info.GetGetMethod(true).Attributes : info.GetSetMethod(true).Attributes;
			IsPublicGet = (attribGet & MethodAttributes.Public) == MethodAttributes.Public;
			ReturnType = info.PropertyType;
			GetterMethod = "GetProperty";
		}
	}
}
